/* 
 * Copyright (C) 2018 Igor Maznitsa.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */
package com.igormaznitsa.sciareto.ui.editors.mmeditors;

import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.util.Locale;
import javax.annotation.Nonnull;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.UndoableEditEvent;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import javax.swing.text.TextAction;
import javax.swing.text.Utilities;
import javax.swing.undo.UndoManager;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import com.igormaznitsa.mindmap.ide.commons.SwingUtils;
import com.igormaznitsa.mindmap.model.logger.Logger;
import com.igormaznitsa.mindmap.model.logger.LoggerFactory;
import com.igormaznitsa.mindmap.swing.services.UIComponentFactoryProvider;
import com.igormaznitsa.sciareto.Main;
import com.igormaznitsa.sciareto.preferences.PreferencesManager;
import com.igormaznitsa.sciareto.preferences.SpecificKeys;
import com.igormaznitsa.sciareto.ui.DialogProviderManager;
import com.igormaznitsa.sciareto.ui.Focuser;
import com.igormaznitsa.sciareto.ui.UiUtils;
import java.awt.Font;

public final class NoteEditor extends javax.swing.JPanel {

  private static final long serialVersionUID = -1715683034655322518L;

  private static final Logger LOGGER = LoggerFactory.getLogger(NoteEditor.class);

  public static final Font DEFAULT_FONT = new Font(Font.MONOSPACED, Font.PLAIN, 14);

  private final UndoManager undoManager = new UndoManager(){
    private static final long serialVersionUID = -239961738072597268L;
    @Override
    public void undoableEditHappened(@Nonnull final UndoableEditEvent e) {
      super.undoableEditHappened(e); 
      updateRedoUndoState();
    }
    
  };
  
  private enum Wrapping {

    NONE("none", "off"), //NOI18N
    CHAR_WRAP("char", "char"), //NOI18N
    WORD_WRAP("word", "word"); //NOI18N

    private final String value;
    private final String display;

    private Wrapping(@Nonnull final String val, @Nonnull final String display) {
      this.value = val;
      this.display = display;
    }

    @Nonnull
    public String getValue() {
      return this.value;
    }

    @Nonnull
    public String getDisplay() {
      return this.display;
    }

    @Nonnull
    public Wrapping next() {
      final int index = this.ordinal() + 1;
      if (index >= Wrapping.values().length) {
        return NONE;
      } else {
        return Wrapping.values()[index];
      }
    }

    @Nonnull
    public static Wrapping findFor(@Nonnull final String text) {
      for (final Wrapping w : Wrapping.values()) {
        if (w.value.equalsIgnoreCase(text)) {
          return w;
        }
      }
      return NONE;
    }
  }

  private static final FileFilter TEXT_FILE_FILTER = new FileFilter() {

    @Override
    public boolean accept(final File f) {
      return f.isDirectory() || f.getName().toLowerCase(Locale.ENGLISH).endsWith(".txt"); //NOI18N
    }

    @Override
    public String getDescription() {
      return java.util.ResourceBundle.getBundle("com/igormaznitsa/nbmindmap/i18n/Bundle").getString("PlainTextEditor.fileFilter.description");
    }
  };

  private Wrapping wrapping;

  private static boolean isWhitespaceOrControl(final char c) {
    return Character.isISOControl(c) || Character.isWhitespace(c);
  }

  private void updateRedoUndoState(){
    this.buttonUndo.setEnabled(this.undoManager.canUndo());
    this.buttonRedo.setEnabled(this.undoManager.canRedo());
  }

  private void doUndo(){
    if (this.undoManager.canUndo()){
      this.undoManager.undo();
    }
    updateRedoUndoState();
  }
  
  private void doRedo(){
    if (this.undoManager.canRedo()){
      this.undoManager.redo();
    }
    updateRedoUndoState();
  }
  
  public NoteEditor(@Nonnull final String text) {
    initComponents();

    this.buttonRedo.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask() | KeyEvent.SHIFT_MASK), "do-redo"); //NOI18N
    this.buttonRedo.getActionMap().put("do-redo", new AbstractAction(){ //NOI18N
      private static final long serialVersionUID = -5644390861803492172L;
      @Override
      public void actionPerformed(@Nonnull final ActionEvent e) {
        doRedo();
      }
    });
    
    this.buttonUndo.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()),"do-undo"); //NOI18N
    this.buttonUndo.getActionMap().put("do-undo", new AbstractAction() { //NOI18N
      private static final long serialVersionUID = -5644390861803492172L;
      @Override
      public void actionPerformed(@Nonnull final ActionEvent e) {
        doUndo();
      }
    });
    
    this.editorPane.setComponentPopupMenu(SwingUtils.addTextActions(UIComponentFactoryProvider.findInstance().makePopupMenu()));
    
    this.editorPane.getActionMap().put(DefaultEditorKit.selectWordAction, new TextAction(DefaultEditorKit.selectWordAction) {
      private static final long serialVersionUID = -6477916799997545798L;
      private final Action start = new TextAction("wordStart") { //NOI18N
        private static final long serialVersionUID = 4377386270269629176L;
        @Override
        public void actionPerformed(@Nonnull final ActionEvent e) {
          final JTextComponent target = getTextComponent(e);
          try {
            if (target != null) {
              int offs = target.getCaretPosition();
              final Document doc = target.getDocument();
              final String text = doc.getText(0, doc.getLength());
              int startOffs = offs;
              if (startOffs < text.length()) {
                for (int i = offs; i >= 0; i--) {
                  if (!isWhitespaceOrControl(text.charAt(i))) {
                    startOffs = i;
                  } else {
                    break;
                  }
                }
                target.setCaretPosition(startOffs);
              }
            }
          } catch (BadLocationException ex) {
            UIManager.getLookAndFeel().provideErrorFeedback(target);
          }
        }
      };
      private final Action end = new TextAction("wordEnd") { //NOI18N
        private static final long serialVersionUID = 4377386270269629176L;
        @Override
        public void actionPerformed(@Nonnull final ActionEvent e) {
          final JTextComponent target = getTextComponent(e);
          try {
            if (target != null) {
              int offs = target.getCaretPosition();

              final Document doc = target.getDocument();
              final String text = doc.getText(0, doc.getLength());
              int endOffs = offs;
              for (int i = offs; i < text.length(); i++) {
                endOffs = i;
                if (isWhitespaceOrControl(text.charAt(i))) {
                  break;
                }
              }
              if (endOffs < text.length() && !isWhitespaceOrControl(text.charAt(endOffs))) {
                endOffs++;
              }
              target.moveCaretPosition(endOffs);
            }
          } catch (BadLocationException ex) {
            UIManager.getLookAndFeel().provideErrorFeedback(target);
          }
        }
      };

      @Override
      public void actionPerformed(@Nonnull final ActionEvent e) {
        this.start.actionPerformed(e);
        this.end.actionPerformed(e);
      }

    });

    this.setPreferredSize(new Dimension(640, 480));
    this.editorPane.setFont(PreferencesManager.getInstance().getFont(PreferencesManager.getInstance().getPreferences(), SpecificKeys.PROPERTY_TEXT_EDITOR_FONT, DEFAULT_FONT));
    this.editorPane.setText(text);
    this.addAncestorListener(new AncestorListener() {
      @Override
      public void ancestorAdded(@Nonnull final AncestorEvent event) {
        SwingUtilities.invokeLater(new Runnable() {
          @Override
          public void run() {
            editorPane.grabFocus();
            updateCaretPos();
          }
        });
      }

      @Override
      public void ancestorRemoved(@Nonnull final AncestorEvent event) {
      }

      @Override
      public void ancestorMoved(@Nonnull final AncestorEvent event) {
      }
    });

    this.editorPane.addCaretListener(new CaretListener() {
      @Override
      public void caretUpdate(@Nonnull final CaretEvent e) {
        updateCaretPos();
      }
    });

    this.wrapping = Wrapping.WORD_WRAP;
    editorPane.setCaretPosition(0);
    updateWrapping();
    
    this.editorPane.getDocument().addUndoableEditListener(this.undoManager);
    updateRedoUndoState();
    
    UiUtils.makeOwningDialogResizable(this);
    
    new Focuser(this.editorPane);
  }

  private void updateCaretPos() {
    final int pos = this.editorPane.getCaretPosition();
    final int col = getColumn(pos, this.editorPane);
    final int row = getRow(pos, this.editorPane);
    this.labelCursorPos.setText(row + ":" + col); //NOI18N

    final String selectedText = this.editorPane.getSelectedText();
    if (StringUtils.isEmpty(selectedText)) {
      this.buttonCopy.setEnabled(false);
      this.buttonBrowse.setEnabled(false);
    } else {
      this.buttonCopy.setEnabled(true);
      try {
        final URI uri = URI.create(selectedText.trim());
        this.buttonBrowse.setEnabled(uri.isAbsolute());
      } catch (Exception ex) {
        this.buttonBrowse.setEnabled(false);
      }
    }
  }

  private static int getRow(final int pos, final JTextComponent editor) {
    int rn = (pos == 0) ? 1 : 0;
    try {
      int offs = pos;
      while (offs > 0) {
        offs = Utilities.getRowStart(editor, offs) - 1;
        rn++;
      }
    } catch (BadLocationException e) {
      LOGGER.error("Bad location", e); //NOI18N
    }
    return rn;
  }

  private static int getColumn(final int pos, final JTextComponent editor) {
    try {
      return pos - Utilities.getRowStart(editor, pos) + 1;
    } catch (BadLocationException e) {
      LOGGER.error("Bad location", e); //NOI18N
    }
    return -1;
  }

  @Nonnull
  public String getText() {
    return this.editorPane.getText();
  }

  public void dispose() {

  }

  /**
   * This method is called from within the constructor to initialize the form. WARNING: Do NOT modify this code. The content of this method is always regenerated by the Form
   * Editor.
   */
  @SuppressWarnings("unchecked")
  // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
  private void initComponents() {

    jToolBar1 = new javax.swing.JToolBar();
    buttonUndo = new javax.swing.JButton();
    buttonRedo = new javax.swing.JButton();
    buttonImport = new javax.swing.JButton();
    buttonExport = new javax.swing.JButton();
    buttonCopy = new javax.swing.JButton();
    buttonPaste = new javax.swing.JButton();
    buttonBrowse = new javax.swing.JButton();
    buttonClear = new javax.swing.JButton();
    jPanel1 = new javax.swing.JPanel();
    labelCursorPos = new javax.swing.JLabel();
    jSeparator1 = new javax.swing.JSeparator();
    labelWrapMode = new javax.swing.JLabel();
    filler1 = new javax.swing.Box.Filler(new java.awt.Dimension(16, 0), new java.awt.Dimension(16, 0), new java.awt.Dimension(16, 32767));
    jScrollPane2 = new javax.swing.JScrollPane();
    editorPane = new javax.swing.JTextArea();

    setLayout(new java.awt.BorderLayout());

    jToolBar1.setFloatable(false);
    jToolBar1.setRollover(true);

    buttonUndo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/undo.png"))); // NOI18N
    buttonUndo.setMnemonic('u');
    buttonUndo.setText("Undo");
    buttonUndo.setFocusable(false);
    buttonUndo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonUndo.setNextFocusableComponent(buttonRedo);
    buttonUndo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonUndo.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonUndoActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonUndo);

    buttonRedo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/redo.png"))); // NOI18N
    buttonRedo.setMnemonic('r');
    buttonRedo.setText("Redo");
    buttonRedo.setFocusable(false);
    buttonRedo.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonRedo.setNextFocusableComponent(buttonImport);
    buttonRedo.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonRedo.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonRedoActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonRedo);

    buttonImport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/disk16.png"))); // NOI18N
    buttonImport.setMnemonic('i');
    buttonImport.setText("Import");
    buttonImport.setToolTipText("Import text content from UTF8 encoded text file");
    buttonImport.setFocusable(false);
    buttonImport.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonImport.setNextFocusableComponent(buttonExport);
    buttonImport.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonImport.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonImportActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonImport);

    buttonExport.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/file_save16.png"))); // NOI18N
    buttonExport.setMnemonic('e');
    buttonExport.setText("Export");
    buttonExport.setToolTipText("Export text content into UTF8 encoded file");
    buttonExport.setFocusable(false);
    buttonExport.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonExport.setNextFocusableComponent(buttonCopy);
    buttonExport.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonExport.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonExportActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonExport);

    buttonCopy.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/page_copy16.png"))); // NOI18N
    buttonCopy.setMnemonic('c');
    buttonCopy.setText("Copy");
    buttonCopy.setToolTipText("Copy selected text content into clipboard");
    buttonCopy.setFocusable(false);
    buttonCopy.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonCopy.setNextFocusableComponent(buttonPaste);
    buttonCopy.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonCopy.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonCopyActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonCopy);

    buttonPaste.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/paste_plain16.png"))); // NOI18N
    buttonPaste.setMnemonic('p');
    buttonPaste.setText("Paste");
    buttonPaste.setToolTipText("Paste text content from clipboard into current position");
    buttonPaste.setFocusable(false);
    buttonPaste.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonPaste.setNextFocusableComponent(buttonBrowse);
    buttonPaste.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonPaste.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonPasteActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonPaste);

    buttonBrowse.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/link16.png"))); // NOI18N
    buttonBrowse.setMnemonic('b');
    buttonBrowse.setText("Browse");
    buttonBrowse.setToolTipText("Open selected link in browser");
    buttonBrowse.setFocusable(false);
    buttonBrowse.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonBrowse.setNextFocusableComponent(buttonClear);
    buttonBrowse.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonBrowse.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonBrowseActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonBrowse);

    buttonClear.setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/cross16.png"))); // NOI18N
    buttonClear.setMnemonic('a');
    buttonClear.setText("Clear All");
    buttonClear.setToolTipText("Clear all text content");
    buttonClear.setFocusable(false);
    buttonClear.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
    buttonClear.setNextFocusableComponent(editorPane);
    buttonClear.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
    buttonClear.addActionListener(new java.awt.event.ActionListener() {
      public void actionPerformed(java.awt.event.ActionEvent evt) {
        buttonClearActionPerformed(evt);
      }
    });
    jToolBar1.add(buttonClear);

    add(jToolBar1, java.awt.BorderLayout.NORTH);

    jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.RIGHT));

    labelCursorPos.setText("...:...");
    labelCursorPos.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        labelCursorPosMouseClicked(evt);
      }
    });
    jPanel1.add(labelCursorPos);

    jSeparator1.setOrientation(javax.swing.SwingConstants.VERTICAL);
    jSeparator1.setPreferredSize(new java.awt.Dimension(8, 16));
    jPanel1.add(jSeparator1);

    labelWrapMode.setText("...");
    labelWrapMode.setCursor(new java.awt.Cursor(java.awt.Cursor.HAND_CURSOR));
    labelWrapMode.addMouseListener(new java.awt.event.MouseAdapter() {
      public void mouseClicked(java.awt.event.MouseEvent evt) {
        labelWrapModeMouseClicked(evt);
      }
    });
    jPanel1.add(labelWrapMode);
    jPanel1.add(filler1);

    add(jPanel1, java.awt.BorderLayout.PAGE_END);

    editorPane.setColumns(20);
    editorPane.setRows(5);
    editorPane.setNextFocusableComponent(buttonUndo);
    jScrollPane2.setViewportView(editorPane);

    add(jScrollPane2, java.awt.BorderLayout.CENTER);
  }// </editor-fold>//GEN-END:initComponents

  private void labelCursorPosMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_labelCursorPosMouseClicked

  }//GEN-LAST:event_labelCursorPosMouseClicked

  private void labelWrapModeMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_labelWrapModeMouseClicked
    this.wrapping = this.wrapping.next();
    updateWrapping();
  }//GEN-LAST:event_labelWrapModeMouseClicked

  private void updateWrapping() {
    this.editorPane.setWrapStyleWord(this.wrapping != Wrapping.CHAR_WRAP);
    this.editorPane.setLineWrap(this.wrapping != Wrapping.NONE);
    updateBottomPanel();
  }

  private void buttonImportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonImportActionPerformed
    final File toOpen = DialogProviderManager.getInstance().getDialogProvider().msgOpenFileDialog(null, "note-editor", UiUtils.BUNDLE.getString("PlainTextEditor.buttonLoadActionPerformed.title"), null, true, TEXT_FILE_FILTER, "Open"); //NOI18N
    if (toOpen != null) {
      try {
        final String text = FileUtils.readFileToString(toOpen, "UTF-8"); //NOI18N
        this.editorPane.setText(text);
      } catch (Exception ex) {
        LOGGER.error("Error during text file loading", ex); //NOI18N
        DialogProviderManager.getInstance().getDialogProvider().msgError(Main.getApplicationFrame(), UiUtils.BUNDLE.getString("PlainTextEditor.buttonLoadActionPerformed.msgError"));
      }
    }

  }//GEN-LAST:event_buttonImportActionPerformed

  private void buttonExportActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonExportActionPerformed
    final File toSave = DialogProviderManager.getInstance().getDialogProvider().msgSaveFileDialog(null, "note-editor", UiUtils.BUNDLE.getString("PlainTextEditor.buttonSaveActionPerformed.saveTitle"), null, true, TEXT_FILE_FILTER, "Save"); //NOI18N
    if (toSave != null) {
      try {
        final String text = getText();
        FileUtils.writeStringToFile(toSave, text, "UTF-8"); //NOI18N
      } catch (Exception ex) {
        LOGGER.error("Error during text file saving", ex); //NOI18N
        DialogProviderManager.getInstance().getDialogProvider().msgError(Main.getApplicationFrame(), UiUtils.BUNDLE.getString("PlainTextEditor.buttonSaveActionPerformed.msgError"));
      }
    }

  }//GEN-LAST:event_buttonExportActionPerformed

  private void buttonCopyActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonCopyActionPerformed
    StringSelection stringSelection = new StringSelection(this.editorPane.getSelectedText());
    final Clipboard clpbrd = Toolkit.getDefaultToolkit().getSystemClipboard();
    clpbrd.setContents(stringSelection, null);
  }//GEN-LAST:event_buttonCopyActionPerformed

  private void buttonPasteActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonPasteActionPerformed
    try {
      this.editorPane.replaceSelection((String) Toolkit.getDefaultToolkit().getSystemClipboard().getData(DataFlavor.stringFlavor));
    } catch (UnsupportedFlavorException ex) {
      // no text data in clipboard
    } catch (IOException ex) {
      LOGGER.error("Error during paste from clipboard", ex); //NOI18N
    }
  }//GEN-LAST:event_buttonPasteActionPerformed

  private void buttonClearActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonClearActionPerformed
    this.editorPane.setText(""); //NOI18N
  }//GEN-LAST:event_buttonClearActionPerformed

  private void buttonBrowseActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonBrowseActionPerformed
    final String selectedText = this.editorPane.getSelectedText().trim();
    try {
      UiUtils.browseURI(URI.create(selectedText), false);
    } catch (Exception ex) {
      LOGGER.error("Can't open link : " + selectedText); //NOI18N
      DialogProviderManager.getInstance().getDialogProvider().msgError(Main.getApplicationFrame(), "Can't browse link : " + selectedText);
    }
  }//GEN-LAST:event_buttonBrowseActionPerformed

  private void buttonUndoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonUndoActionPerformed
    doUndo();
  }//GEN-LAST:event_buttonUndoActionPerformed

  private void buttonRedoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_buttonRedoActionPerformed
    doRedo();
  }//GEN-LAST:event_buttonRedoActionPerformed

  private void updateBottomPanel() {
    this.labelWrapMode.setText("Wrap: " + this.wrapping.getDisplay());
  }


  // Variables declaration - do not modify//GEN-BEGIN:variables
  private javax.swing.JButton buttonBrowse;
  private javax.swing.JButton buttonClear;
  private javax.swing.JButton buttonCopy;
  private javax.swing.JButton buttonExport;
  private javax.swing.JButton buttonImport;
  private javax.swing.JButton buttonPaste;
  private javax.swing.JButton buttonRedo;
  private javax.swing.JButton buttonUndo;
  private javax.swing.JTextArea editorPane;
  private javax.swing.Box.Filler filler1;
  private javax.swing.JPanel jPanel1;
  private javax.swing.JScrollPane jScrollPane2;
  private javax.swing.JSeparator jSeparator1;
  private javax.swing.JToolBar jToolBar1;
  private javax.swing.JLabel labelCursorPos;
  private javax.swing.JLabel labelWrapMode;
  // End of variables declaration//GEN-END:variables
}
